#!/usr/bin/env bun
/**
 * BSS模拟客户端 - 用于测试BSS TCP服务
 */

const net = require('node:net')
const iconv = require('iconv-lite')

class BSSSimulator {
  constructor(options = {}) {
    this.host = options.host || '127.0.0.1'
    this.port = options.port || 4000
    this.encoding = options.encoding || 'gbk'
    this.client = null
    this.messageBuffer = Buffer.alloc(0)
  }

  /**
   * 连接到BSS服务器
   */
  connect() {
    return new Promise((resolve, reject) => {
      this.client = net.createConnection({
        host: this.host,
        port: this.port
      })
      
      this.client.on('connect', () => {
        console.log(`✅ 连接到BSS服务器 ${this.host}:${this.port}`)
        this.setupHandlers()
        resolve()
      })
      
      this.client.on('error', (error) => {
        console.error('❌ 连接错误:', error.message)
        reject(error)
      })
    })
  }

  /**
   * 设置事件处理器
   */
  setupHandlers() {
    this.client.on('data', (data) => {
      this.handleData(data)
    })
    
    this.client.on('close', () => {
      console.log('🔌 连接已关闭')
    })
    
    this.client.on('error', (error) => {
      console.error('❌ 错误:', error.message)
    })
  }

  /**
   * 处理接收到的数据
   */
  handleData(data) {
    // 添加到缓冲区
    this.messageBuffer = Buffer.concat([this.messageBuffer, data])
    
    // 解析消息
    while (this.messageBuffer.length >= 8) {
      // 读取消息长度
      const length = this.messageBuffer.readUInt32BE(0)
      
      if (this.messageBuffer.length < length + 4) {
        // 消息不完整
        break
      }
      
      // 读取命令码
      const command = this.messageBuffer.readUInt32BE(4)
      
      // 读取消息体
      const messageBuffer = this.messageBuffer.slice(8, length + 4)
      const message = iconv.decode(messageBuffer, this.encoding)
      
      console.log(`📥 收到消息 [${command}]:`, message)
      
      // 尝试解析JSON
      try {
        const data = JSON.parse(message)
        console.log('   解析数据:', data)
      } catch (e) {
        // 不是JSON格式
      }
      
      // 更新缓冲区
      this.messageBuffer = this.messageBuffer.slice(length + 4)
    }
  }

  /**
   * 发送消息
   */
  sendMessage(command, data) {
    if (!this.client) {
      console.error('❌ 未连接到服务器')
      return
    }
    
    // 编码消息
    const message = JSON.stringify(data)
    const messageBuffer = iconv.encode(message, this.encoding)
    
    // 构造完整消息
    const length = messageBuffer.length + 4
    const fullMessage = Buffer.allocUnsafe(8 + messageBuffer.length)
    
    fullMessage.writeUInt32BE(length, 0)
    fullMessage.writeUInt32BE(command, 4)
    messageBuffer.copy(fullMessage, 8)
    
    // 发送
    this.client.write(fullMessage)
    console.log(`📤 发送消息 [${command}]:`, data)
  }

  /**
   * 关闭连接
   */
  disconnect() {
    if (this.client) {
      this.client.end()
      this.client = null
    }
  }
}

/**
 * 测试场景
 */
async function runTests() {
  const simulator = new BSSSimulator({
    host: '127.0.0.1',
    port: 4000
  })
  
  try {
    // 连接到服务器
    await simulator.connect()
    
    // 等待心跳消息
    console.log('\n⏳ 等待心跳消息...')
    await new Promise(resolve => setTimeout(resolve, 6000))
    
    // 测试1: 发送登录消息
    console.log('\n🔐 测试登录...')
    simulator.sendMessage(1001, {
      ID: '001',
      Pwd: '',
      Type: 'TEST',
      Name: 'BSS模拟器'
    })
    await new Promise(resolve => setTimeout(resolve, 1000))
    
    // 测试2: 发送地址解析请求
    console.log('\n📍 测试地址解析...')
    simulator.sendMessage(4000, {
      address: '南京市鼓楼区中山北路',
      city: '南京市'
    })
    await new Promise(resolve => setTimeout(resolve, 1000))
    
    // 测试3: 发送坐标转换请求
    console.log('\n🗺️ 测试坐标转换...')
    simulator.sendMessage(4002, {
      lon: 118.7969,
      lat: 32.0603,
      from: 'gcj02',
      to: 'bd09'
    })
    await new Promise(resolve => setTimeout(resolve, 1000))
    
    // 测试4: 发送车辆位置请求
    console.log('\n🚑 测试车辆位置查询...')
    simulator.sendMessage(4004, {
      carId: 'AMB001'
    })
    await new Promise(resolve => setTimeout(resolve, 1000))
    
    // 测试5: 发送调度请求
    console.log('\n📋 测试调度请求...')
    simulator.sendMessage(4019, {
      taskId: 'TASK' + Date.now(),
      carId: 'AMB001',
      address: '南京市鼓楼医院',
      priority: 'HIGH'
    })
    await new Promise(resolve => setTimeout(resolve, 1000))
    
    // 测试6: 批量消息
    console.log('\n📦 测试批量消息...')
    simulator.sendMessage(4011, {
      batch: [
        { type: 'location', carId: 'AMB001' },
        { type: 'location', carId: 'AMB002' },
        { type: 'status', carId: 'AMB001' }
      ]
    })
    await new Promise(resolve => setTimeout(resolve, 2000))
    
    // 保持连接一段时间观察心跳
    console.log('\n💓 观察心跳消息（15秒）...')
    await new Promise(resolve => setTimeout(resolve, 15000))
    
  } catch (error) {
    console.error('❌ 测试失败:', error)
  } finally {
    // 断开连接
    console.log('\n👋 断开连接')
    simulator.disconnect()
  }
}

// 主程序
async function main() {
  console.log('🚀 BSS模拟器启动')
  console.log('================================')
  
  await runTests()
  
  console.log('================================')
  console.log('✅ 测试完成')
  process.exit(0)
}

// 运行主程序
if (require.main === module) {
  main().catch(error => {
    console.error('❌ 程序错误:', error)
    process.exit(1)
  })
}

module.exports = BSSSimulator